/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#include "SBJ/Arrow/MsgProxy.h"

namespace SBJ
{

namespace Arrow
{

inline const std::string&
Publication::getKey( void ) const
{
	return m_key;
}

template< typename MsgType > void
Publication::publish( void )
{
	boost::mutex::scoped_lock lock( m_guard );

	std::pair< KeyedMsgProxys::iterator, bool > result = m_msgProxys.insert(
		std::make_pair( typeid( MsgType ).name(), 
		static_cast< MsgProxy* >( 0 ) ) );
	if ( result.second == true )
	{
		result.first->second = new TMsgProxy< MsgType >( m_excObserver );
	}
}

template< typename MsgType, typename Allocator > void
Publication::publishWithAlloc( const Allocator& allocator )
{
	boost::mutex::scoped_lock lock( m_guard );

	std::pair< KeyedMsgProxys::iterator, bool > result = m_msgProxys.insert(
		std::make_pair( typeid( MsgType ).name(), 
		static_cast< MsgProxy* >( 0 ) ) );
	if ( result.second == true )
	{
		result.first->second = new TMsgProxy< MsgType, Allocator >( m_excObserver, allocator );
	}
}

template< typename MsgType > Topic
Publication::makeTopic( const std::string& topicKey )
{
	boost::mutex::scoped_lock lock( m_guard );
	const MsgProxy* MsgProxy = getMsgProxy<MsgType>();
	return makeTopic( MsgProxy, topicKey );
}

inline Topic
Publication::makeTopic( const std::string& topicKey )
{
	boost::mutex::scoped_lock lock( m_guard );
	const MsgProxy* MsgProxy = getMsgProxy();
	return makeTopic( MsgProxy, topicKey );
}

template< typename MsgType > Topic
Publication::getTopic( const std::string& topicKey ) const
{
	boost::mutex::scoped_lock lock( m_guard );

	const MsgProxy* msgProxy = getMsgProxy< MsgType >();
	if ( msgProxy != 0 )
	{
		if ( topicKey.empty() == true )
		{
			return Topic( this, msgProxy );
		}
		else
		{
			KeyedTopics::const_iterator iter = m_topics.find( topicKey );
			if ( iter != m_topics.end() && iter->second->use > 0 )
			{
				if ( msgProxy == iter->second->msgProxy )
				{
					return Topic( this, iter->second ); 
				}
			}
		}
	}
	return Topic();
}

template< typename MsgType > const MsgProxy*
Publication::getMsgProxy( void ) const
{
	KeyedMsgProxys::const_iterator iter( m_msgProxys.find( typeid( MsgType ).name() ) );
	if ( iter != m_msgProxys.end() )
	{
		return iter->second;
	}
	return 0;
}

}

}

